﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.SqlClient;
using AdmLaboratorios.DTO;
using AdmLaboratorios.DAO;
using AdmLaboratorios.Business.Entities;

namespace AdmLaboratorios.Business
{
    public static class Seguridad
    {
        static UsuarioDAO daoUsuario = DAOFactory.Get<UsuarioDAO>();
        static PermisoDAO daoPermiso = DAOFactory.Get<PermisoDAO>();
        static PerfilDAO daoPerfil = DAOFactory.Get<PerfilDAO>();
        static UsuarioPerfilDAO daoUsuarioPerfil = DAOFactory.Get<UsuarioPerfilDAO>();

        public static UsuarioDTO Read(int id)
        {
            return daoUsuario.Read(id);
        }

        public static List<PermisoDTO> PermisosByUsuarioInstitucion(int idUsuario, int idInstitucion)
        {
            return daoPermiso.GetByUsuarioInstitucion(idUsuario, idInstitucion);
        }

        public static bool Login(string usuario, string password, out UsuarioDTO u)
        {
            u = daoUsuario.Read(string.Format("Usuario='{0}' AND Password='{1}'", usuario, password));

            if (u != null)
                return true;
            else
                return false;
        }

        public static List<PermisoDTO> PermisosByPerfil(int idPerfil)
        {
            return daoPermiso.ReadAll("IdPerfil = " + idPerfil.ToString());
        }

        public static List<PerfilDTO> Perfiles()
        {
            return daoPerfil.ReadAll();
        }

        public static List<PerfilDTO> PerfilesByUsuarioInstitucion(int idUsuario, int idInstitucion)
        {
            List<PerfilDTO> perfiles = new List<PerfilDTO>();

            foreach (UsuarioPerfilDTO usuarioPerfil in daoUsuarioPerfil.ReadAll(
                string.Format("IdUsuario={0} AND IdInstitucion={1}", idUsuario, idInstitucion)))
            {
                perfiles.Add(daoPerfil.Read(usuarioPerfil.IdPerfil));
            }
            return perfiles;
        }

        public static void LimpiarPermisosByPerfil(int idPefil)
        {
            SqlTransaction tran = null;

            try
            {
                tran = daoPermiso.IniciarTransaccion();

                daoPermiso.Log(LogDTO.eAcciones.Baja
                    , "LimpiarPermisosByPerfil", idPefil, tran);

                daoPermiso.Delete("IdPerfil = " + idPefil.ToString(), tran);

                daoPermiso.CommitTransaccion(tran);
            }
            catch (Exception)
            {
                if (tran != null) daoPermiso.RollbackTransaccion(tran);
                throw;
            }
        }

        public static void CrearPermiso(int idPerfil, string nombreMenu)
        {
            SqlTransaction tran = null;

            try
            {
                tran = daoPermiso.IniciarTransaccion();

                PermisoDTO p = new PermisoDTO();

                p.NombreMenu = nombreMenu.Trim();
                p.IdPerfil = idPerfil;

                p = daoPermiso.Create(p, tran);

                daoPermiso.Log(LogDTO.eAcciones.Alta
                    , "CrearPermiso", p.Id, "NombreMenu", "", p.NombreMenu, tran);

                daoPermiso.CommitTransaccion(tran);
            }
            catch (Exception)
            {
                if (tran != null) daoPermiso.RollbackTransaccion(tran);
                throw;
            }
        }

        public static List<UsuarioPerfiles> UsuariosPerfiles()
        {
            List<UsuarioPerfiles> r = new List<UsuarioPerfiles>();
            foreach (var usuario in daoUsuario.ReadAll())
            {
                r.Add(new UsuarioPerfiles(usuario));
            }
            return r;
        }

        public static bool ExisteUsuario(string nombre)
        {
            return (daoUsuario.ReadAll(string.Format("Usuario='{0}'", nombre))).Count > 0;
        }

        public static UsuarioDTO AltaDeUsuario(string usuario, string contraseña)
        {
            SqlTransaction tran = null;

            try
            {
                tran = daoUsuario.IniciarTransaccion();

                UsuarioDTO u = new UsuarioDTO();

                u.Usuario = usuario.Trim();
                u.Password = contraseña.Trim();

                u = daoUsuario.Create(u, tran);

                daoUsuario.Log(LogDTO.eAcciones.Alta
                    , "AltaDeUsuario", u.Id, "Usuario", "", u.Usuario, tran);

                daoUsuario.CommitTransaccion(tran);
                return u;
            }
            catch (Exception)
            {
                if (tran != null) daoPermiso.RollbackTransaccion(tran);
                throw;
            }
        }

        public static UsuarioDTO ModificacionDeUsuario(int idUsuario, string usuario, string contraseña)
        {
            SqlTransaction tran = null;
            UsuarioDTO n;
            try
            {
                tran = daoUsuario.IniciarTransaccion();
                n = daoUsuario.Read(idUsuario);

                daoUsuario.Log(LogDTO.eAcciones.Modificacion
                    , "ModificacionDeUsuario", n.Id, "Usuario", n.Usuario, usuario, tran);

                n.Usuario = usuario.Trim();
                n.Password = contraseña.Trim();

                daoUsuario.Update(n, idUsuario, tran);
                daoUsuario.CommitTransaccion(tran);
                return n;
            }
            catch (Exception)
            {
                daoUsuario.RollbackTransaccion(tran);
                throw;
            }
        }

        public static void BajaDeUsuario(int idUsuario)
        {
            SqlTransaction tran = null;
            UsuarioDTO n;
            try
            {
                tran = daoUsuario.IniciarTransaccion();
                n = daoUsuario.Read(idUsuario);

                daoUsuario.Log(LogDTO.eAcciones.Baja
                    , "BajaDeUsuario", n.Id, "Usuario", n.Usuario, "", tran);

                daoUsuarioPerfil.Delete("IdUsuario = " + idUsuario.ToString(), tran);
                daoUsuario.Delete(idUsuario, tran);
                daoUsuario.CommitTransaccion(tran);
            }
            catch (Exception)
            {
                daoUsuario.RollbackTransaccion(tran);
                throw;
            }
        }

        public static void DeletePerfil(int idPerfil)
        {
            SqlTransaction tran = null;
            PerfilDTO perfil;
            try
            {
                tran = daoPerfil.IniciarTransaccion();
                perfil = daoPerfil.Read(idPerfil);

                daoPerfil.Log(LogDTO.eAcciones.Baja
                    , "DeletePerfil", perfil.Id, "Nombre", perfil.Nombre, "", tran);

                daoPerfil.Delete(idPerfil, tran);
                daoPerfil.CommitTransaccion(tran);
            }
            catch (Exception)
            {
                daoPerfil.RollbackTransaccion(tran);
                throw;
            }
        }

        public static PerfilDTO AltaPerfil(string nombre)
        {
            SqlTransaction tran = null;

            try
            {
                tran = daoPerfil.IniciarTransaccion();

                PerfilDTO perfil = new PerfilDTO();

                perfil.Nombre = nombre.Trim();

                perfil = daoPerfil.Create(perfil, tran);

                daoPerfil.Log(LogDTO.eAcciones.Alta
                    , "AltaPerfil", perfil.Id, "Nombre", "", perfil.Nombre, tran);

                daoPerfil.CommitTransaccion(tran);
                return perfil;
            }
            catch (Exception)
            {
                if (tran != null) daoPerfil.RollbackTransaccion(tran);
                throw;
            }
        }

        public static void AsignarPerfiles(int idUsuario, List<PerfilDTO> perfiles)
        {
            SqlTransaction tran = null;

            try
            {
                tran = daoUsuarioPerfil.IniciarTransaccion();
                daoUsuarioPerfil.Delete("IdUsuario = " + idUsuario.ToString(), tran);
                CrearUsuarioPerfil(idUsuario, perfiles, tran);

                daoUsuarioPerfil.Log(LogDTO.eAcciones.Otra
                    , "AsignarPerfiles", idUsuario, tran);

                daoUsuarioPerfil.CommitTransaccion(tran);
            }
            catch (Exception)
            {
                if (tran != null) daoUsuarioPerfil.RollbackTransaccion(tran);
                throw;
            }
        }

        private static void CrearUsuarioPerfil(int idUsuario, List<PerfilDTO> perfiles, SqlTransaction tran)
        {
            UsuarioPerfilDTO usuarioPerfil;

            foreach (PerfilDTO perfil in perfiles)
            {
                usuarioPerfil = new UsuarioPerfilDTO();

                usuarioPerfil.IdUsuario = idUsuario;
                usuarioPerfil.IdPerfil = perfil.Id;

                usuarioPerfil = daoUsuarioPerfil.Create(usuarioPerfil, tran);

                daoUsuarioPerfil.Log(LogDTO.eAcciones.Alta
                , "CrearUsuarioPerfil", usuarioPerfil.Id, "Nombre", "", perfil.Nombre, tran);
            }
        }

        public static List<PerfilDTO> PerfilesByUsuario(UsuarioDTO usuario)
        {
            List<PerfilDTO> perfiles = new List<PerfilDTO>();
            var UsuarioPerfiles = daoUsuarioPerfil.ReadAll("IdUsuario=" + usuario.Id);

            foreach (var usuarioPerfil in UsuarioPerfiles)
                perfiles.Add(daoPerfil.Read(usuarioPerfil.IdPerfil)); 

            return perfiles;
        }

        public static List<PermisoDTO> PermisosByPerfiles(List<PerfilDTO> perfiles)
        {
            List<PermisoDTO> permisos = new List<PermisoDTO>();
            foreach (var perfil in perfiles)
            {
                foreach (var permiso in daoPermiso.ReadAll("IdPerfil=" + perfil.Id))
                {
                    if (!permisos.Contains(permiso))
                        permisos.Add(permiso);
	            } 
            }

            return permisos;
        }

        public static UsuarioDTO GetUsuario(int idUsuario)
        {
            return daoUsuario.Read(idUsuario);
        }
    }
}
